package com.smartcampusbackend.service.impl;

import com.smartcampusbackend.mapper.AnnouncementMapper;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.model.Announcement;
import com.smartcampusbackend.model.AnnouncementAttachment;
import com.smartcampusbackend.model.UserReadStatus;
import com.smartcampusbackend.service.AnnouncementService;
import com.smartcampusbackend.service.ActivitySignupService;
import com.smartcampusbackend.service.UserReadStatusService;
import com.smartcampusbackend.service.AnnouncementAttachmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AnnouncementServiceImpl implements AnnouncementService {
    @Autowired
    private AnnouncementMapper announcementMapper;
    
    @Autowired
    @Lazy
    private ActivitySignupService activitySignupService;
    
    @Autowired
    private UserReadStatusService userReadStatusService;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private AnnouncementAttachmentService announcementAttachmentService;

    @Override
    @Transactional
    public int publishAnnouncement(Announcement announcement) {
        // 设置发布时间
        announcement.setPublishTime(new Date());
        // 明确设置为非草稿
        announcement.setIsDraft(false);
        
        // 如果是活动，设置默认状态为报名中
        if ("ACTIVITY".equals(announcement.getType())) {
            announcement.setStatus("SIGNUP_OPEN");
        } else {
            // 新闻和通知类型清空地址信息
            announcement.setLocation(null);
        }
        
        int result = announcementMapper.insertAnnouncement(announcement);
        
        // 处理附件 - 确保公告ID已设置
        if (result > 0 && announcement.getId() != null && announcement.getAttachments() != null && !announcement.getAttachments().isEmpty()) {
            for (Map<String, Object> attachment : announcement.getAttachments()) {
                AnnouncementAttachment announcementAttachment = new AnnouncementAttachment();
                announcementAttachment.setAnnouncementId(announcement.getId());
                announcementAttachment.setFileUrl((String) attachment.get("url"));
                announcementAttachment.setFileName((String) attachment.get("name"));
                announcementAttachmentService.addAttachment(announcementAttachment);
            }
        }
        
        // 为新公告为所有用户创建阅读状态记录（包括活动）
        if (result > 0 && announcement.getId() != null) {
            try {
                List<Integer> allUserIds = getAllUserIds();
                if (!allUserIds.isEmpty()) {
                    userReadStatusService.initializeAnnouncementReadStatus(announcement.getId(), allUserIds);
                }
            } catch (Exception e) {
                // 静默处理异常
            }
        }
        
        return result;
    }

    @Override
    public Announcement getAnnouncementById(Integer id) {
        Announcement announcement = announcementMapper.selectAnnouncementById(id);
        if (announcement != null) {
            // 获取附件信息
            List<AnnouncementAttachment> attachments = announcementAttachmentService.getAttachmentsByAnnouncementId(id);
            if (attachments != null && !attachments.isEmpty()) {
                List<Map<String, Object>> attachmentList = attachments.stream()
                    .map(att -> {
                        Map<String, Object> map = new HashMap<>();
                        map.put("id", att.getId());
                        map.put("name", att.getFileName());
                        map.put("url", att.getFileUrl());
                        return map;
                    })
                    .collect(Collectors.toList());
                announcement.setAttachments(attachmentList);
            }
        }
        return announcement;
    }

    @Override
    public List<Announcement> getAnnouncements(String type, String publisher) {
        List<Announcement> announcements = announcementMapper.selectAnnouncements(type, publisher);
        // 为每个公告加载附件信息
        for (Announcement announcement : announcements) {
            loadAttachmentsForAnnouncement(announcement);
        }
        return announcements;
    }

    @Override
    public List<Announcement> getAnnouncements(String type, String publisher, String keyword, Integer page, Integer size) {
        int offset = (page - 1) * size;
        List<Announcement> announcements = announcementMapper.selectAnnouncementsWithSearch(type, publisher, keyword, offset, size);
        // 为每个公告加载附件信息
        for (Announcement announcement : announcements) {
            loadAttachmentsForAnnouncement(announcement);
        }
        return announcements;
    }

    @Override
    public int getAnnouncementsCount(String type, String publisher, String keyword) {
        return announcementMapper.selectAnnouncementsCount(type, publisher, keyword);
    }

    @Override
    public int updateActivityStatus(Integer id, String status) {
        return announcementMapper.updateActivityStatus(id, status);
    }

    @Override
    public void checkAndUpdateActivityStatus(Integer activityId) {
        Announcement activity = getAnnouncementById(activityId);
        if (activity == null || !"ACTIVITY".equals(activity.getType())) {
            return;
        }

        String newStatus = "SIGNUP_OPEN";
        
        // 检查是否已截止
        if (activity.getSignupDeadline() != null && new Date().after(activity.getSignupDeadline())) {
            newStatus = "SIGNUP_CLOSED";
        }
        
        // 检查是否已满员
        if (activity.getActivityLimit() != null) {
            int approvedCount = activitySignupService.getApprovedSignupCount(activityId);
            if (approvedCount >= activity.getActivityLimit()) {
                newStatus = "FULL";
            }
        }
        
        // 如果状态需要更新，则更新
        if (!newStatus.equals(activity.getStatus())) {
            updateActivityStatus(activityId, newStatus);
        }
    }

    @Override
    public List<Map<String, Object>> getAnnouncementsWithReadStatus(String type, String publisher, Integer userId) {
        List<Announcement> announcements = getAnnouncements(type, publisher);
        
        return announcements.stream().map(announcement -> {
            Map<String, Object> result = new HashMap<>();
            result.put("announcement", announcement);
            
            // 为所有类型的公告添加阅读状态（包括活动）
            if (userId != null) {
                UserReadStatus readStatus = userReadStatusService.getReadStatus(userId, announcement.getId());
                result.put("isRead", readStatus != null && readStatus.getIsRead());
                result.put("readTime", readStatus != null ? readStatus.getReadTime() : null);
            }
            
            // 为活动类型添加已通过的人数信息
            if ("ACTIVITY".equals(announcement.getType())) {
                int approvedCount = activitySignupService.getApprovedSignupCount(announcement.getId());
                result.put("approvedCount", approvedCount);
            }
            
            return result;
        }).collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> getAnnouncementsWithReadStatus(String type, String publisher, Integer userId, String keyword, Integer page, Integer size) {
        List<Announcement> announcements = getAnnouncements(type, publisher, keyword, page, size);
        
        return announcements.stream().map(announcement -> {
            Map<String, Object> result = new HashMap<>();
            result.put("announcement", announcement);
            
            // 为所有类型的公告添加阅读状态（包括活动）
            if (userId != null) {
                UserReadStatus readStatus = userReadStatusService.getReadStatus(userId, announcement.getId());
                result.put("isRead", readStatus != null && readStatus.getIsRead());
                result.put("readTime", readStatus != null ? readStatus.getReadTime() : null);
            }
            
            // 为活动类型添加已通过的人数信息
            if ("ACTIVITY".equals(announcement.getType())) {
                int approvedCount = activitySignupService.getApprovedSignupCount(announcement.getId());
                result.put("approvedCount", approvedCount);
            }
            
            return result;
        }).collect(Collectors.toList());
    }

    @Override
    public Announcement getAnnouncementWithReadStatus(Integer id, Integer userId) {
        Announcement announcement = getAnnouncementById(id);
        if (announcement != null && userId != null) {
            // 为所有类型的公告标记为已读（包括活动）
            userReadStatusService.markAsRead(userId, id);
        }
        return announcement;
    }
    
    @Override
    @Transactional
    public int deleteAnnouncement(Integer id, String publisher) {
        // 先检查公告是否存在且是否为发布者
        Announcement announcement = getAnnouncementById(id);
        if (announcement == null) {
            throw new RuntimeException("公告不存在");
        }
        
        if (!announcement.getPublisher().equals(publisher)) {
            throw new RuntimeException("只有发布者可以删除公告");
        }
        
        try {
            // 1. 删除相关的阅读状态记录
            userReadStatusService.deleteReadStatusByAnnouncementId(id);
            
            // 2. 如果是活动，删除相关的报名记录
            if ("ACTIVITY".equals(announcement.getType())) {
                activitySignupService.deleteSignupsByActivityId(id);
            }
            
            // 3. 删除相关的附件记录
            announcementAttachmentService.deleteAttachmentsByAnnouncementId(id);
            
            // 4. 最后删除公告本身
            int result = announcementMapper.deleteAnnouncement(id);
            
            return result;
        } catch (Exception e) {
            throw new RuntimeException("删除公告失败: " + e.getMessage());
        }
    }
    
    @Override
    public int saveDraft(Announcement announcement) {
        // 设置草稿状态
        announcement.setIsDraft(true);
        Date now = new Date();
        announcement.setDraftTime(now);
        announcement.setPublishTime(now);
        
        // 如果是活动，设置默认状态为报名中
        if ("ACTIVITY".equals(announcement.getType())) {
            announcement.setStatus("SIGNUP_OPEN");
        } else {
            // 新闻和通知类型清空地址信息
            announcement.setLocation(null);
        }
        
        return announcementMapper.insertAnnouncement(announcement);
    }
    
    @Override
    public int updateDraft(Announcement announcement) {
        // 检查是否为草稿
        Announcement existingDraft = getAnnouncementById(announcement.getId());
        if (existingDraft == null) {
            throw new RuntimeException("草稿不存在");
        }
        
        if (!existingDraft.getIsDraft()) {
            throw new RuntimeException("只能更新草稿");
        }
        
        if (!existingDraft.getPublisher().equals(announcement.getPublisher())) {
            throw new RuntimeException("只有发布者可以更新草稿");
        }
        
        // 更新草稿时间，保持原有的发布时间
        Date now = new Date();
        announcement.setDraftTime(now);
        announcement.setIsDraft(true);
        announcement.setPublishTime(existingDraft.getPublishTime()); // 保持原有的发布时间
        
        // 如果是新闻或通知类型，清空地址信息
        if (!"ACTIVITY".equals(announcement.getType())) {
            announcement.setLocation(null);
        }
        
        return announcementMapper.updateAnnouncement(announcement);
    }
    
    @Override
    public List<Announcement> getDrafts(String publisher, String type) {
        List<Announcement> drafts = announcementMapper.selectDrafts(publisher, type);
        // 为每个草稿加载附件信息
        for (Announcement draft : drafts) {
            loadAttachmentsForAnnouncement(draft);
        }
        return drafts;
    }
    
    @Override
    @Transactional
    public int publishDraft(Integer id, String publisher) {
        // 检查草稿是否存在且是否为发布者
        Announcement draft = getAnnouncementById(id);
        if (draft == null) {
            throw new RuntimeException("草稿不存在");
        }
        
        if (!draft.getIsDraft()) {
            throw new RuntimeException("只能发布草稿");
        }
        
        if (!draft.getPublisher().equals(publisher)) {
            throw new RuntimeException("只有发布者可以发布草稿");
        }
        
        try {
            // 如果是新闻或通知类型，清空地址信息
            if (!"ACTIVITY".equals(draft.getType())) {
                draft.setLocation(null);
                announcementMapper.updateAnnouncement(draft);
            }
            
            // 发布草稿
            int result = announcementMapper.publishDraft(id, new Date());
            
            // 如果是新闻、通知或活动，为所有用户创建阅读状态记录
            if (result > 0 && ("NEWS".equals(draft.getType()) || "NOTICE".equals(draft.getType()) || "ACTIVITY".equals(draft.getType()))) {
                try {
                    List<Integer> allUserIds = getAllUserIds();
                    if (!allUserIds.isEmpty()) {
                        userReadStatusService.initializeAnnouncementReadStatus(id, allUserIds);
                    }
                } catch (Exception e) {
                    // 静默处理异常
                }
            }
            
            return result;
        } catch (Exception e) {
            throw new RuntimeException("发布草稿失败: " + e.getMessage());
        }
    }
    
    @Override
    public int deleteDraft(Integer id, String publisher) {
        // 检查草稿是否存在且是否为发布者
        Announcement draft = getAnnouncementById(id);
        if (draft == null) {
            throw new RuntimeException("草稿不存在");
        }
        
        if (!draft.getIsDraft()) {
            throw new RuntimeException("只能删除草稿");
        }
        
        if (!draft.getPublisher().equals(publisher)) {
            throw new RuntimeException("只有发布者可以删除草稿");
        }
        
        return announcementMapper.deleteAnnouncement(id);
    }
    
    // 获取所有用户ID的辅助方法
    private List<Integer> getAllUserIds() {
        // 这里需要根据你的UserMapper实现来调整
        // 假设UserMapper有一个selectAllUserIds方法
        try {
            List<Integer> userIds = userMapper.selectAllUserIds();
            return userIds != null ? userIds : List.of();
        } catch (Exception e) {
            // 如果方法不存在或出现异常，返回空列表
            return List.of();
        }
    }

    private void loadAttachmentsForAnnouncement(Announcement announcement) {
        // 实现加载附件信息的逻辑
        // 这里需要根据你的AnnouncementAttachmentService实现来调整
        // 假设AnnouncementAttachmentService有一个getAttachmentsByAnnouncementId方法
        List<AnnouncementAttachment> attachments = announcementAttachmentService.getAttachmentsByAnnouncementId(announcement.getId());
        if (attachments != null && !attachments.isEmpty()) {
            List<Map<String, Object>> attachmentList = attachments.stream()
                .map(att -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", att.getId());
                    map.put("name", att.getFileName());
                    map.put("url", att.getFileUrl());
                    return map;
                })
                .collect(Collectors.toList());
            announcement.setAttachments(attachmentList);
        }
    }
} 